/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Persistencia.Oracle;

import Persistencia.DAOFactory;
import Persistencia.Entidades.BoletaSenasa;
import Persistencia.Entidades.PagoSenasa;
import Persistencia.IPagoSenasaDAO;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import oracle.jdbc.OraclePreparedStatement;
import oracle.jdbc.OracleTypes;
import utilidades.FormatDateString;

/**
 *
 * @author zeta
 */
public class PagoSenasaOracleDAO implements IPagoSenasaDAO {

    private static PagoSenasaOracleDAO INSTANCE = null;

    /*
     * El contrustcor private no permite que se genere un constructor por defecto
     */
    private PagoSenasaOracleDAO() {
    }

    private synchronized static void createInstance() {
        if (INSTANCE == null) {
            INSTANCE = new PagoSenasaOracleDAO();
        }
    }

    public static PagoSenasaOracleDAO getInstance() {
        if (INSTANCE == null) {
            createInstance();
        }
        return INSTANCE;
    }

    public Integer insertPagoSenasa(PagoSenasa pagoSenasa) {
        String sql = "INSERT INTO PAGOSSENASA  ( NUM_PAGO, FECHA_EMISION, IMPORTE)"
                + "VALUES(?,TO_DATE(?, 'DD/MM/RRRR'),?) RETURNING NUM_PAGO INTO ? ";
        Connection conn = OracleDAOFactory.getConnection();
        try {


            OraclePreparedStatement pst = (OraclePreparedStatement) conn.prepareStatement(sql);
            pst.setInt(1, pagoSenasa.getNumPago());
            pst.setString(2, FormatDateString.deDateString(pagoSenasa.getFechaEmision()));
            pst.setFloat(3, pagoSenasa.getImporte());
            pst.registerReturnParameter(4, OracleTypes.NUMBER);
            //inicia Transaccion
            conn.setAutoCommit(false);
            pst.executeUpdate();
            
            //NO SE PUEDE INSERTAR UN PAGO QUE NO TENGA BOLETAS
            if (pagoSenasa.getBoletasSenasaList()==null) {
                conn.rollback();

            } else {
                Iterator<BoletaSenasa> e = pagoSenasa.getBoletasSenasaList().iterator();
                while (e.hasNext()) {
                    BoletaSenasa boletaSenasa = e.next();
                    String sql1 = "INSERT INTO PAGOBOLETAS  (NUM_PAGO, NUM_BOLETA) VALUES(?,?)";
                    OraclePreparedStatement pst1 = (OraclePreparedStatement) conn.prepareStatement(sql1);
                    pst1.setInt(1, pagoSenasa.getNumPago());
                    pst1.setInt(2, boletaSenasa.getNumBoleta());
                    pst1.executeUpdate();
                }

                conn.commit();
            }
            ResultSet rs = pst.getReturnResultSet();
            if (rs.next()) {
                return rs.getInt(1);
            }
            return null;
        } catch (SQLException ex) {
            try {
                conn.rollback();
            } catch (SQLException ex1) {
                ex1.printStackTrace();
            }
            ex.printStackTrace();
            return null;
        } finally {
            try {
                conn.setAutoCommit(true);
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        }
    }

    public boolean cancelPagoSenasa(PagoSenasa pagoSenasa, Date fechaPago) {
        if (!pagoSenasa.getCancelado()) {
            String sql = "UPDATE PAGOSSENASA SET FECHA_PAGO = TO_DATE(?, 'DD/MM/RRRR'),"
                    + "CANCELADO = '1'  WHERE NUM_PAGO = ?";

            Connection conn = OracleDAOFactory.getConnection();
            try {


                OraclePreparedStatement pst = (OraclePreparedStatement) OracleDAOFactory.getConnection().prepareStatement(sql);
                pst.setString(1, FormatDateString.deDateString(fechaPago));
                pst.setInt(2, pagoSenasa.getNumPago());

                //inicia Transaccion
                conn.setAutoCommit(false);
                pst.executeUpdate();
                //NO SE PUEDE CANCELAR UN PAGO QUE NO TENGA BOLETAS
                if (pagoSenasa.getBoletasSenasaList().isEmpty()) {
                    conn.rollback();

                } else {
                    Iterator<BoletaSenasa> e = pagoSenasa.getBoletasSenasaList().iterator();
                    while (e.hasNext()) {
                        BoletaSenasa boletaSenasa = e.next();
                        String sql1 = "UPDATE BOLETASSENASA SET PAGA = '1' WHERE NUM_BOLETA = ? ";
                        OraclePreparedStatement pst1 = (OraclePreparedStatement) conn.prepareStatement(sql1);
                        pst1.setInt(1, boletaSenasa.getNumBoleta());
                        pst1.execute();
                    }
                    conn.commit();
                }
                //Una vez actualizado en la base de datos actualizo el objeto
                pagoSenasa = DAOFactory.getDAOFactory(DAOFactory.ORACLE).getPagoSenasaDAO().getPagoSenasa(pagoSenasa.getNumPago());
                return true;

            } catch (SQLException ex) {
                try {
                    conn.rollback();
                } catch (SQLException ex1) {
                    ex1.printStackTrace();
                }
                ex.printStackTrace();
                return false;
            } finally {
                try {
                    conn.setAutoCommit(true);
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            }
        }
        /*
         * else{
         * trhow new PagoCanceladoException(El pago ya esta cancelado);
         * }
         */
        return false;
    }

    public boolean updatePagoSenasa(PagoSenasa pagoSenasa) {
        if (!pagoSenasa.getCancelado()) {
            String sql = "UPDATE PAGOSSENASA SET IMPORTE = ?"
                    + "WHERE NUM_PAGO = ?";

            Connection conn = OracleDAOFactory.getConnection();
            try {


                OraclePreparedStatement pst = (OraclePreparedStatement) OracleDAOFactory.getConnection().prepareStatement(sql);
                pst.setFloat(1, pagoSenasa.getImporte());
                pst.setInt(2, pagoSenasa.getNumPago());
                //inicia Transaccion
                conn.setAutoCommit(false);
                pst.executeUpdate();
                String sql1 = "DELETE FROM PAGOBOLETAS WHERE NUM_PAGO = ?";
                OraclePreparedStatement pst1 = (OraclePreparedStatement) OracleDAOFactory.getConnection().prepareStatement(sql1);
                pst1.setInt(1, pagoSenasa.getNumPago());
                pst1.executeUpdate();
                if (pagoSenasa.getBoletasSenasaList().isEmpty()) {
                    conn.rollback();
                } else {
                    Iterator<BoletaSenasa> e = pagoSenasa.getBoletasSenasaList().iterator();
                    while (e.hasNext()) {
                        BoletaSenasa boletaSenasa = e.next();
                        String sql2 = "INSERT INTO PAGOBOLETAS  (NUM_PAGO, NUM_BOLETA) VALUES(?,?)";
                        OraclePreparedStatement pst2 = (OraclePreparedStatement) conn.prepareStatement(sql1);
                        pst2.setInt(1, pagoSenasa.getNumPago());
                        pst2.setInt(2, boletaSenasa.getNumBoleta());
                        pst2.execute();
                    }
                    conn.commit();
                      //Una vez actualizado en la base de datos actualizo el objeto
                pagoSenasa = DAOFactory.getDAOFactory(DAOFactory.ORACLE).getPagoSenasaDAO().getPagoSenasa(pagoSenasa.getNumPago());
                }

                return true;
            } catch (SQLException ex) {
                ex.printStackTrace();
                try {
                    conn.rollback();
                } catch (SQLException ex1) {
                    ex1.printStackTrace();
                }
                return false;
            } finally {
                try {
                    conn.setAutoCommit(true);
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            }
        }
        /*
         * else{
         * trhow new PagoCanceladoException(El pago ya esta cancelado);
         * }
         */
        return false;
    }

    public PagoSenasa getPagoSenasa(Integer numPago) {
        String sql = "SELECT NUM_PAGO,  FECHA_EMISION, IMPORTE,  FECHA_PAGO, CANCELADO FROM PAGOSSENASA"
                + " WHERE NUM_PAGO = ?";
        try {

            OraclePreparedStatement pst = (OraclePreparedStatement) OracleDAOFactory.getConnection().prepareStatement(sql);
            pst.setInt(1, numPago);
            ResultSet rs = pst.executeQuery();
            if (rs.next()) {
                PagoSenasa pagoSenasa = new PagoSenasa();
                pagoSenasa.setNumPago(rs.getInt("NUM_PAGO"));
                pagoSenasa.setFechaEmision(new java.util.Date(rs.getDate("FECHA_EMISION").getTime()));
                pagoSenasa.setImporte(rs.getFloat("IMPORTE"));
                pagoSenasa.setFechaPago(rs.getDate("FECHA_PAGO")==null ? null:new java.util.Date(rs.getDate("FECHA_PAGO").getTime()));
                pagoSenasa.setCancelado(rs.getString("CANCELADO").equals("0") ? false : true);
                //Carga el objeto pagoSenasa Con Todas las boletas que le corresponden a dicho pago
                DAOFactory.getDAOFactory(DAOFactory.ORACLE).getBoletaSenasaDAO().getAllBoletasSenasa(pagoSenasa, false);


                return pagoSenasa;
            } else {
                return null;
            }
        } catch (SQLException ex) {
            ex.printStackTrace();
            return null;
        }
    }

    public List<PagoSenasa> getAllPagosSenasa() {
        String sql = "SELECT NUM_PAGO,  FECHA_EMISION, IMPORTE,  FECHA_PAGO, CANCELADO FROM PAGOSSENASA";


        try {
            OraclePreparedStatement pst = (OraclePreparedStatement) OracleDAOFactory.getConnection().prepareStatement(sql);
            ResultSet rs = pst.executeQuery();
            List<PagoSenasa> lPagosSenasa = new ArrayList();
            while (rs.next()) {
                PagoSenasa pagoSenasa = new PagoSenasa();
                pagoSenasa.setNumPago(rs.getInt("NUM_PAGO"));
                pagoSenasa.setFechaEmision(new java.util.Date(rs.getDate("FECHA_EMISION").getTime()));
                pagoSenasa.setImporte(rs.getFloat("IMPORTE"));
                pagoSenasa.setFechaPago(new java.util.Date(rs.getDate("FECHA_PAGO").getTime()));
                pagoSenasa.setCancelado(rs.getString("CANCELADO").equals("0") ? false : true);
                DAOFactory.getDAOFactory(DAOFactory.ORACLE).getBoletaSenasaDAO().getAllBoletasSenasa(pagoSenasa, false);
                lPagosSenasa.add(pagoSenasa);
            }

            return lPagosSenasa;
        } catch (SQLException ex) {
            ex.printStackTrace();
            return null;
        }
    }

    public List<PagoSenasa> getCancelPagosSenasa() {
        String sql = "SELECT NUM_PAGO,  FECHA_EMISION, IMPORTE,  FECHA_PAGO, CANCELADO FROM PAGOSSENASA" +
                "WHERE CANCELADO <> '0'";


        try {
            OraclePreparedStatement pst = (OraclePreparedStatement) OracleDAOFactory.getConnection().prepareStatement(sql);
            ResultSet rs = pst.executeQuery();
            List<PagoSenasa> lPagosSenasa = new ArrayList();
            while (rs.next()) {
                PagoSenasa pagoSenasa = new PagoSenasa();
                pagoSenasa.setNumPago(rs.getInt("NUM_PAGO"));
                pagoSenasa.setFechaEmision(new java.util.Date(rs.getDate("FECHA_EMISION").getTime()));
                pagoSenasa.setImporte(rs.getFloat("IMPORTE"));
                pagoSenasa.setFechaPago(new java.util.Date(rs.getDate("FECHA_PAGO").getTime()));
                pagoSenasa.setCancelado(rs.getString("CANCELADO").equals("0") ? false : true);
                DAOFactory.getDAOFactory(DAOFactory.ORACLE).getBoletaSenasaDAO().getAllBoletasSenasa(pagoSenasa, false);
                lPagosSenasa.add(pagoSenasa);
            }

            return lPagosSenasa;
        } catch (SQLException ex) {
            ex.printStackTrace();
            return null;
        }
    }

    public List<PagoSenasa> getNotCancelPagosSenasa() {
        String sql = "SELECT NUM_PAGO,  FECHA_EMISION, IMPORTE,  FECHA_PAGO, CANCELADO FROM PAGOSSENASA" +
                "WHERE CANCELADO = '0'";


        try {
            OraclePreparedStatement pst = (OraclePreparedStatement) OracleDAOFactory.getConnection().prepareStatement(sql);
            ResultSet rs = pst.executeQuery();
            List<PagoSenasa> lPagosSenasa = new ArrayList();
            while (rs.next()) {
                PagoSenasa pagoSenasa = new PagoSenasa();
                pagoSenasa.setNumPago(rs.getInt("NUM_PAGO"));
                pagoSenasa.setFechaEmision(new java.util.Date(rs.getDate("FECHA_EMISION").getTime()));
                pagoSenasa.setImporte(rs.getFloat("IMPORTE"));
                pagoSenasa.setFechaPago(new java.util.Date(rs.getDate("FECHA_PAGO").getTime()));
                pagoSenasa.setCancelado(rs.getString("CANCELADO").equals("0") ? false : true);
                DAOFactory.getDAOFactory(DAOFactory.ORACLE).getBoletaSenasaDAO().getAllBoletasSenasa(pagoSenasa, false);
                lPagosSenasa.add(pagoSenasa);
            }

            return lPagosSenasa;
        } catch (SQLException ex) {
            ex.printStackTrace();
            return null;
        }
    }

    public boolean deletePagoSenasa(PagoSenasa pagoSenasa) {
        if (!pagoSenasa.getCancelado()) {
             try {
                String sql = "DELETE PAGOSSENASA WHERE NUM_PAGO = ?";
                OraclePreparedStatement pst = (OraclePreparedStatement) OracleDAOFactory.getConnection().prepareStatement(sql);
                pst.setInt(1, pagoSenasa.getNumPago());
                pst.executeUpdate();
                return true;
            } catch (SQLException ex) {
                ex.printStackTrace();
                return false;
            }

        }
        return false;
    }
}
